package com.yoki.cloud.common.protocol.portal.msg;

import com.yoki.cloud.common.protocol.portal.msg.attr.MsgAttr;
import com.yoki.cloud.common.utils.encrypt.EncryptUtils;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * @author Sky$
 * @Description: TODO
 * @date 2017/10/25$ 14:53$
 */
@Data
@NoArgsConstructor
public class PortalV2Msg extends AbstractPortalMsg {

    private static Integer SECRET_LENGTH = 16;

    private String secret;

    private byte[] md5Authenticator;

    public PortalV2Msg(int ver, int type, int serialNo, int reqId, String userIp, int errCode, int attrNum, List<MsgAttr> attrList,
                       String secret) {
        super();
        this.ver = ver;
        this.type = type;
        this.serialNo = serialNo;
        this.reqId = reqId;
        this.userIp = userIp;
        this.errCode = errCode;
        this.attrNum = attrNum;
        this.attrList = attrList;
        this.secret = secret;
    }

    public PortalV2Msg(int ver, int type, int papChap, int rsvd, int serialNo, int reqId, String userIp, int userPort, int errCode, int attrNum, List<MsgAttr> attrList) {
        super();
        this.ver = ver;
        this.type = type;
        this.papChap = papChap;
        this.rsvd = rsvd;
        this.serialNo = serialNo;
        this.reqId = reqId;
        this.userIp = userIp;
        this.userPort = userPort;
        this.errCode = errCode;
        this.attrNum = attrNum;
        this.attrList = attrList;
    }


    /**
     * 返回华为TLV数据报文
     *
     * @return
     */
    @Override
    public byte[] toByteArray() {
        byte[] b = toExcludemd5AuthenticatorByteArray();
        md5Authenticator = getAuthenticator();
        if (null != md5Authenticator && md5Authenticator.length > 0 && md5Authenticator.length == PortalV2Msg.SECRET_LENGTH) {
            System.arraycopy(md5Authenticator, 0, b, PortalV2Msg.HEADER_LENGTH, PortalV2Msg.SECRET_LENGTH);
        }
        return b;
    }

    protected byte[] toExcludemd5AuthenticatorByteArray() {
        byte[] headerBytes = getHander16Bytes();
        byte[] attrBytes = getAttrBytes();
        byte[] b = new byte[headerBytes.length + 16 + attrBytes.length];
        if (null != headerBytes && headerBytes.length > 0) {
            System.arraycopy(headerBytes, 0, b, 0, headerBytes.length);
        }
        b[15] = (byte) this.attrList.size();
        if (null != attrBytes && attrBytes.length > 0) {
            System.arraycopy(attrBytes, 0, b, 32, attrBytes.length);
        }
        return b;
    }

    @Override
    public void parse(byte[] input) {

        if (null != input && input.length >= (AbstractPortalMsg.HEADER_LENGTH + PortalV2Msg.SECRET_LENGTH)) {
            byte[] headerBytes = new byte[AbstractPortalMsg.HEADER_LENGTH];
            System.arraycopy(input, 0, headerBytes, 0, headerBytes.length);
            this.parseHeader(headerBytes);

            System.arraycopy(input, AbstractPortalMsg.HEADER_LENGTH, md5Authenticator, 0, AbstractPortalMsg.HEADER_LENGTH);
            int attrNum = input[AbstractPortalMsg.HEADER_LENGTH - 1];

            byte[] attrBytes = new byte[input.length - (AbstractPortalMsg.HEADER_LENGTH + PortalV2Msg.SECRET_LENGTH)];
            System.arraycopy(input, (AbstractPortalMsg.HEADER_LENGTH + PortalV2Msg.SECRET_LENGTH), attrBytes, 0, attrBytes.length);
            parseAttr(attrBytes, attrNum);
        }

    }

    protected byte[] getAuthenticator() {
        byte[] a = toExcludemd5AuthenticatorByteArray();
        byte[] b = new byte[a.length + secret.getBytes().length];
        System.arraycopy(a, 0, b, 0, a.length);
        System.arraycopy(secret.getBytes(), 0, b, a.length, secret.getBytes().length);
        return getMD5Bytes(b);
    }

    /**
     * 对字符串md5加密
     *
     * @return
     */
    protected byte[] getMD5Bytes(byte[] a) {
        return EncryptUtils.encryptMD5Bytes(a);
    }

}
